/*
 * Copyright Aristool AG Switzerland
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
package org.opprua.tidy.gens;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.opprua.tidy.util.CodePrint;

/**
 * TODO: add Java doc
 * 
 * Prepared for first commit: 15.04.2007
 * 
 * @author Lin Li
 */
public class GState extends Gtor {

  private List<Object> statements = new ArrayList<Object>();
  private String head = null;
  private String tail = null;

  public GState() {
  }

  /**
   * adds a statement
   * 
   * @param statement
   *          The statement to add
   */
  public GState addStatement(Gtor statement) {
    this.statements.add(statement);
    return this;
  }

  /**
   * adds a statement. If the statement is already semicolumn terminated, it
   * will not be terminated again. If the statement contains cr('\n')s, the new
   * lines will be indented properly.
   * 
   * @param statement
   *          The statement to add
   */
  public GState addStatement(String statement) {
    if (statement == null) { return this; }
    String s = statement.trim();
    if (s.length() == 0) { return this; }

    if (s.endsWith(";")) {
      s = s.substring(0, s.length() - 1);
    }
    if (s.indexOf("\n") > 0) {
      StringTokenizer st = new StringTokenizer(s, "\n");
      boolean first = true;
      while (st.hasMoreElements()) {
        String ss = st.nextToken().trim();
        if (first) {
          this.statements.add(ss + " ");
          first = false;
        } else {
          this.statements.add("    " + ss + " ");
        }
      }
      this.statements.add("");
    } else {
      this.statements.add(s);
    }
    return this;
  }

  /**
   * @param string
   */
  public void setHead(String string) {
    head = string;
  }

  /**
   * @param string
   */
  public void setTail(String string) {
    tail = string;
  }

  /**
   * @see Gtor#dump(CodePrint w)
   */
  public void dump(CodePrint w) {

    if (head != null && head.trim().length() > 0) {
      w.print(head.trim());
      w.print(" ");
    }
    w.println("{");
    w.einruecken();

    for (Iterator<Object> i = statements.iterator(); i.hasNext();) {
      Object p = i.next();
      if (p instanceof String) {
        String s = (String) p;
        if (s.length() == 0) {
          w.println(";");
        } else if (s.endsWith(" ")) {
          if (s.startsWith("    ")) {
            w.println();
          }
          s = s.substring(0, s.length() - 1);
          w.print(s);
        } else {
          w.print(s);
          w.println(";");
        }
      } else {
        ((Gtor) p).dump(w);
        w.println();
      }
    }

    w.ausruecken();
    w.print("}");
    if (tail != null && tail.trim().length() > 0) {
      w.print(" ");
      w.print(tail.trim());
      w.print(";");
    }
  }
  
  public int getNumberOfStatements() {
    return statements.size();
  }
}
